class Snake {
    // 蛇头
    head: HTMLElement
    //身体
    body: HTMLCollection
    // 获取蛇容器
    element: HTMLElement

    constructor() {
        // 找到蛇容器
        this.element = document.getElementById("snake")!
        // 找到蛇头
        this.head = document.querySelector("#snake > div")!
        // 找到蛇的身体
        this.body = this.element.getElementsByTagName("div")
    }

    // 获取蛇头x坐标的
    get X(): number {
        return this.head.offsetLeft
    }

    // 设置蛇头x坐标的
    set X(value: number) {
        // 如果坐标不变就不修改，防止重复渲染dom
        if (this.X === value) {
            return
        }
        // 判断是否越界(撞墙)
        if (value < 0 || value > 290) {
            throw new Error("撞墙")
        }
        // 判断是否是调头：头位置和前一节身体重合
        if (this.body[1] && (this.body[1] as HTMLElement).offsetLeft === value) {
            // 反方向继续走
            if (value > this.X) {
                value = this.X - 10
            } else {
                value = this.X + 10
            }
        }
        // 移动身体
        this.moveBody()
        this.head.style.left = value + 'px'
        // 检查有没有撞到自己
        this.checkHeadBody()
    }

    // 获取蛇头Y坐标的
    get Y(): number {
        return this.head.offsetTop
    }

    // 设置蛇头Y坐标的
    set Y(value: number) {
        if (this.Y === value) {
            return
        }
        if (value < 0 || value > 290) {
            throw new Error("撞墙")
        }
        if (this.body[1] && (this.body[1] as HTMLElement).offsetTop === value) {
            if (value > this.Y) {
                value = this.Y - 10
            } else {
                value = this.Y + 10
            }
        }
        this.moveBody()
        this.head.style.top = value + 'px'
        this.checkHeadBody()
    }

    // 增加身体
    addBody(): void {
        this.element.insertAdjacentHTML('beforeend', '<div></div>')
    }

    // 移动身体
    moveBody(): void {
        // 从后往前移动
        for (let i = this.body.length - 1; i > 0; i--) {
            // 获取前一个位置
            let x = (this.body[i - 1] as HTMLElement).offsetLeft;
            let y = (this.body[i - 1] as HTMLElement).offsetTop;
            // 把当前位置移动到前一个位置上去
            (this.body[i] as HTMLElement).style.left = x + 'px';
            (this.body[i] as HTMLElement).style.top = y + 'px';
        }
    }

    // 检查头和身体是否重叠
    checkHeadBody(): void {
        for (let i = 1; i < this.body.length; i++) {
            let body = this.body[i] as HTMLElement
            if (this.X === body.offsetLeft && this.Y === body.offsetTop) {
                throw new Error("撞到自己")
            }
        }
    }
}

export default Snake